
namespace WindowsAPI
{
    public static partial class Keyboard
    {
        public class Key
        {
            /* ------------------------------------------------------------------------------------------ */

            public static bool CapsLock { get { return IsKeySwiched(VirtualKey.CapsLock); } set { if(value != CapsLock) Key_Enter(VirtualKey.CapsLock); } }

            public static bool NumLock { get { return IsKeySwiched(VirtualKey.NumLock); } set { if(value != NumLock) Key_Enter(VirtualKey.NumLock); } }

            public static bool ScrolLock { get { return IsKeySwiched(VirtualKey.ScrollLock); } set { if(value != ScrolLock) Key_Enter(VirtualKey.ScrollLock); } }

            /* ------------------------------------------------------------------------------------------ */

            public static bool IsKeyAsyncPressed(VirtualKey key) { return (User32.Keyboard.GetAsyncKeyState(key) & 0x8000) == 0x8000; }
            public static bool IsKeyPressed(VirtualKey key) { return (User32.Keyboard.GetKeyState(key) & 0x8000) == 0x8000; }
            public static bool IsKeyAsyncSwiched(VirtualKey key) { return (User32.Keyboard.GetAsyncKeyState(key) & 0x0001) == 0x0001; }
            public static bool IsKeySwiched(VirtualKey key) { return (User32.Keyboard.GetKeyState(key) & 0x0001) == 0x0001; }

            public static void Key_Press(VirtualKey key)
            {
                User32.SendInput(1,
                    new[]
                    {
                        new Input
                            {
                                type = InputType.INPUT_KEYBOARD,
                                Keyboard = new KeyboardInput
                                                {
                                                    VirtualKeyCode = (VirtualKeyShort)key
                                                }
                            }//,
                        //new Input
                        //    {
                        //        type = InputType.INPUT_KEYBOARD,
                        //        Keyboard = new KeyboardInput
                        //                       {
                        //                            VirtualKeyCode = (VirtualKeyShort)key,
                        //                            Flags = KeyEventF.KEYUP
                        //                       }
                        //    }
                    }, Input.Size);
            }

            public static void Key_Up(VirtualKey key)
            {
                User32.SendInput(1,
                    new[]
                    {
                        //new Input
                        //    {
                        //        type = InputType.INPUT_KEYBOARD,
                        //        Keyboard = new KeyboardInput
                        //                       {
                        //                            VirtualKeyCode = (VirtualKeyShort)key
                        //                       }
                        //    },
                        new Input
                            {
                                type = InputType.INPUT_KEYBOARD,
                                Keyboard = new KeyboardInput
                                                {
                                                    VirtualKeyCode = (VirtualKeyShort)key,
                                                    Flags = KeyEventF.KEYUP
                                                }
                            }
                    }, Input.Size);
            }

            public static void Key_Enter(VirtualKey key)
            {
                User32.SendInput(2,
                    new[]
                        {
                            new Input
                                {
                                    type = InputType.INPUT_KEYBOARD,
                                    Keyboard =  new KeyboardInput  {VirtualKeyCode = (VirtualKeyShort)key}
                                },
                            new Input
                                {
                                    type = InputType.INPUT_KEYBOARD,
                                    Keyboard = new KeyboardInput
                                                   {
                                                        VirtualKeyCode = (VirtualKeyShort)key,
                                                        Flags = KeyEventF.KEYUP
                                                   }
                                }
                        }, Input.Size);
            }

            /* ------------------------------------------------------------------------------------------ */

            private VirtualKey f_VirtualKey;

            /* ------------------------------------------------------------------------------------------ */

            public VirtualKey VirtualKey { get { return f_VirtualKey; } set { f_VirtualKey = value; } }

            //public bool Pressed_Async { get { return IsKeyAsyncPressed(f_VirtualKey); } }
            public bool Pressed
            {
                get { return IsKeyAsyncPressed(f_VirtualKey); }
                set
                {
                    if(value != Pressed)
                        if(value)
                            Key_Press(f_VirtualKey);
                        else
                            Key_Up(f_VirtualKey);
                }
            }

            public bool Swiched { get { return IsKeyAsyncSwiched(f_VirtualKey); } set { if(value != Swiched) Press(); } }
            //public bool Swiched_Async { get { return IsKeyAsyncSwiched(f_VirtualKey); } }

            /* ------------------------------------------------------------------------------------------ */

            public Key() { }
            public Key(VirtualKey key) { f_VirtualKey = key; }

            /* ------------------------------------------------------------------------------------------ */

            public void Press() { Key_Enter(f_VirtualKey); }

            /* ------------------------------------------------------------------------------------------ */
        }
    }
}